using System;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;

namespace InfiniTec.IO
{
	internal static class SafeNativeMethods
	{
		[DllImport("Kernel32.dll", SetLastError = true)]
		public static extern MemoryMappedFileSafeHandle CreateFileMapping(
			SafeFileHandle hFile,
			IntPtr securityAttributes,
			uint flProtect,
			uint dwMaximumSizeHigh,
			uint dwMaximumSizeLow,
			string lpName);

		[DllImport("Kernel32.dll")]
		public static extern void CopyMemory(IntPtr destination, IntPtr source, IntPtr count);

		[DllImport("Kernel32.dll", CharSet = CharSet.Auto, EntryPoint = "RtlSecureZeroMemory")]
		public static extern void SecureZeroMemory(IntPtr handle, IntPtr size);

		[DllImport("Kernel32.dll", SetLastError = true)]
		public static extern bool CloseHandle(IntPtr handle);

		[DllImport("Kernel32.dll", SetLastError = true)]
		public static extern IntPtr MapViewOfFile(
			MemoryMappedFileSafeHandle hFileMappingObject,
			FileMapAccesses dwDesiredAccess,
			uint dwFileOffsetHigh,
			uint dwFileOffsetLow,
			uint dwNumberOfBytesToMap);

		[DllImport("Kernel32.dll", SetLastError = true)]
		public static extern void UnmapViewOfFile(IntPtr lpBaseAddress);

		[DllImport("kernel32.dll")]
		public static extern void GetSystemInfo([MarshalAs(UnmanagedType.Struct)] ref SystemInfo lpSystemInfo);
	}

	internal enum FileProtection : uint
	{
		Readonly = 0x2,
		ReadWrite = 0x4,
		WriteCopy = 0x8,
		ExecuteRead = 0x20,
		ExecuteReadWrite = 0x40
	}
	internal enum FileOptions : uint
	{
		Commit = 0x8000000,
		Image = 0x1000000,
		LargePages = 0x80000000,
		NoCache = 0x10000000,
		Reserve = 0x4000000,
	}

	[StructLayout(LayoutKind.Sequential)]
	internal struct SystemInfo
	{
		internal ProcessorInfoUnion uProcessorInfo;
		public uint dwPageSize;
		public IntPtr lpMinimumApplicationAddress;
		public IntPtr lpMaximumApplicationAddress;
		public IntPtr dwActiveProcessorMask;
		public uint dwNumberOfProcessors;
		public uint dwProcessorType;
		public uint dwAllocationGranularity;
		public ushort dwProcessorLevel;
		public ushort dwProcessorRevision;
	}

	[StructLayout(LayoutKind.Explicit)]
	internal struct ProcessorInfoUnion
	{
		[FieldOffset(0)]
		internal uint dwOemId;
		[FieldOffset(0)]
		internal ushort wProcessorArchitecture;
		[FieldOffset(2)]
		internal ushort wReserved;
	}
}